/*
 * 文件名：ExceptionAdvice.java
 * 版权：MoonBox 
 * 修改人：Peter
 * 修改时间：2018年10月11日
 * 修改内容：新增
 */
package com.renzhebiao.lkang.exception;

import java.util.List;

import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.renzhebiao.lkang.master.Dict;
import com.renzhebiao.lkang.master.ResultVO;
import com.renzhebiao.lkang.master.ResultVO.ResultVOBuilder;
import com.renzhebiao.lkang.request.RequestCache;
import com.renzhebiao.lkang.request.RequestPayload;
import com.renzhebiao.lkang.utils.Exceptions;

import lombok.extern.log4j.Log4j;

/**
 * <p>
 * 异常处理
 * 
 * @author Peter
 * @since 1.0.0
 */
@Log4j
@ControllerAdvice
public class ExceptionAdvice {

    /**
     * 拦截捕捉自定义状态异常 StatusException.class
     * 
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = StatusException.class)
    public ResultVO<Void> myErrorHandler(StatusException ex) {
        fail();
        log.error(Exceptions.getStackTrace(ex));
        int code = ex.getCode();
        // String msg = Statuss.getMsg(code);
        String msg = ex.getDesc();
        // if (EmptyTools.notNull(ex.getDesc())) {
        // msg = ex.getDesc();
        // }
        // if (EmptyTools.notNull(ex.getParams())) {
        // msg = Strings.format(msg, ex.getParams());
        // }
        ResultVOBuilder<Void> rs = ResultVO.builder();
        return rs.code(code).msg(msg).build();
    }

    @ResponseBody
    @ExceptionHandler({ArithmeticException.class})
    public ResultVO<Void> myErrorHandler(ArithmeticException ex) {
        fail();
        log.error(Exceptions.getStackTrace(ex));
        int code = 2;
        // String msg = Statuss.getMsg(code);
        String msg = ex.getMessage();
        // if (EmptyTools.notNull(ex.getDesc())) {
        // msg = ex.getDesc();
        // }
        // if (EmptyTools.notNull(ex.getParams())) {
        // msg = Strings.format(msg, ex.getParams());
        // }
        ResultVOBuilder<Void> rs = ResultVO.builder();
        return rs.code(code).msg(msg).build();
    }

    /**
     * Validator 校验失败异常处理
     * 
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResultVO<Void> errorHandler(MethodArgumentNotValidException ex) {
        fail();
        log.error(Exceptions.getStackTrace(ex));
        // int code = StatusCode.BadRequest.BAD_REQUEST_FORMAT;
        int code = 3;
        List<ObjectError> es = ex.getBindingResult().getAllErrors();
        ObjectError e = es.get(0);
        ResultVOBuilder<Void> rs = ResultVO.builder();
        return rs.code(code).msg(e.getDefaultMessage()).build();
    }

    /**
     * 请求参数解析异常，Spring Jackson Json Convert
     * 
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    public ResultVO<Void> messageErrorHandler(HttpMessageNotReadableException ex) {
        fail();
        log.error(Exceptions.getStackTrace(ex));
        // int code = StatusCode.BadRequest.BAD_REQUEST_FORMAT;
        // String msg = Strings.format(Statuss.getMsg(code), "请求的");
        int code = 403001;
        String msg = "参数错误";
        ResultVOBuilder<Void> rs = ResultVO.builder();
        return rs.code(code).msg(msg).build();
    }

    /**
     * 全局异常捕捉处理
     * 
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ResultVO<Void> errorHandler(Exception ex) {
        fail();
        log.error(Exceptions.getStackTrace(ex));
        // int code = StatusCode.ServerError.UNKNOW_ERROR;
        int code = 1;
        // String msg = Statuss.getMsg(code);
        String msg = "系统错误";
        ResultVOBuilder<Void> rs = ResultVO.builder();
        return rs.code(code).msg(msg).build();
    }

    private void fail() {
        RequestPayload req = RequestCache.get();
        if (req != null) {
            req.setSucceed(Dict.Whether.NO);
        }
    }

}
